#include "OgreGLES2DepthBuffer.h"
#include "OgreGLES2HardwarePixelBuffer.h"
#include "OgreGLES2RenderSystem.h"
#include "OgreGLES2FrameBufferObject.h"

namespace Ogre
{
	GLES2DepthBuffer::GLES2DepthBuffer(uint16 poolId, GLES2RenderSystem* renderSystem, GLES2Context* creatorContext,
									GLES2RenderBuffer* depth, GLES2RenderBuffer* stencil,
									uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuality,
									bool isManual) :
		DepthBuffer(poolId, 0, width, height, fsaa, "", isManual),
		mMultiSampleQuality(multiSampleQuality),
		mCreatorContext(creatorContext),
		mDepthBuffer(depth),
		mStencilBuffer(stencil),
		mRenderSystem(renderSystem)
	{
		if (mDepthBuffer)
		{
			switch(mDepthBuffer->getGLFormat())
			{
			case GL_DEPTH_COMPONENT16:
				mBitDepth = 16;
				break;
#if GL_OES_depth24
			case GL_DEPTH_COMPONENT24_OES:
#endif
#if GL_OES_depth32
			case GL_DEPTH_COMPONENT32_OES:
#endif
#if GL_OES_packed_depth_stencil
			case GL_DEPTH24_STENCIL8_OES:
#endif
				mBitDepth = 32;
				break;
			}
		}
	}

	GLES2DepthBuffer::~GLES2DepthBuffer()
	{
		if (mStencilBuffer && mStencilBuffer != mDepthBuffer)
		{
			delete mStencilBuffer;
			mStencilBuffer = 0;
		}
		if (mDepthBuffer)
		{
			delete mDepthBuffer;
			mDepthBuffer = 0;
		}
	}

	bool GLES2DepthBuffer::isCompatible(RenderTarget* renderTarget) const
	{
		bool retVal = false;

		if (mRenderSystem->getCapabilities()->hasCapabilities(RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL))
		{
			if (!DepthBuffer::isCompatible(renderTarget))
				return false;
		}
		else
		{
			if (this->getWidth() != renderTarget->getWidth() ||
				this->getHeight() != renderTarget->getHeight() ||
				this->getFsaa() != renderTarget->getFSAA())
				return false;
		}

		GLESFrameBufferObject* fbo = 0;
		renderTarget->getCustomAttribute("FBO", &fbo);

		if (!fbo)
		{
			GLES2Context* windowContext;
			renderTarget->getCustomAttribute("GLCONTEXT", &windowContext);

			if (!mDepthBuffer && !mStencilBuffer && mCreatorContext == windowContext)
				retVal = true;
		}
		else
		{
			if (mDepthBuffer || mStencilBuffer)
			{
				GLenum internalFormat = fbo->getFormat();
				GLenum depthFormat, stencilFormat;
				mRenderSystem->_getDepthStencilFormatFor(internalFormat, &depthFormat, &stencilFormat);

				bool bSameDepth = false;

				if (mDepthBuffer)
					bSameDepth |= mDepthBuffer->getGLFormat() == depthFormat;

				bool bSameStencil = false;
				if (!mStencilBuffer || mStencilBuffer == mDepthBuffer)
					bSameStencil = stencilFormat == GL_NONE;
				else
				{
					if (mStencilBuffer)
						bSameStencil = stencilFormat == mStencilBuffer->getGLFormat();
				}

				retVal = bSameDepth && bSameStencil;
			}
		}

		return retVal;
	}
}
